package com.xinghanlaser.applet.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xinghanlaser.applet.base.auth.entity.ResourceDO;
import com.xinghanlaser.applet.base.auth.entity.UserDO;
import com.xinghanlaser.applet.base.auth.service.IUserService;
import com.xinghanlaser.applet.base.auth.vo.UserDetailVO;
import com.xinghanlaser.applet.base.common.entity.ResponseEntity;
import com.xinghanlaser.applet.base.common.exception.ServiceException;
import com.xinghanlaser.applet.base.flow.core.IFlowService;
import com.xinghanlaser.applet.base.flow.vo.AccessPointVO;
import com.xinghanlaser.applet.base.flow.vo.PointQueryVO;
import com.xinghanlaser.applet.base.flow.vo.PointVO;
import com.xinghanlaser.applet.entity.TopicHandleDetail;
import com.xinghanlaser.applet.service.ITopicHandleDetailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * <p>
 *
 * @author: mftuo 陀铭峰
 * @since: 2024/5/11 15:01
 */
@RestController
@RequestMapping("/flow")
@Api(value = "节点流程管理", tags = "节点流程管理")
public class FlowController {
    @Resource
    private IUserService userService;

    @Resource
    private IFlowService flowService;

    @Resource
    private ITopicHandleDetailService handleService;

    @GetMapping("/next-point")
    @ApiOperation("获取当前节点的下一个节点列表")
    public ResponseEntity<Set<PointVO>> getNextPointListByCondition(@Valid PointQueryVO queryVO){
        Set<PointVO> result = flowService.getNextPointListByCondition(queryVO);
        return ResponseEntity.ok(result);
    }

    @PostMapping("/next-point")
    @ApiOperation("执行当前节点")
    public ResponseEntity<Void> nextPoint(@RequestBody @Valid AccessPointVO vo){
        final Long topicId = vo.getTopicId();
        final Long pointId = vo.getPointId();

        // 校验操作权限
        validatedRoleAccess(pointId);

        // 获取最新当前节点
        Long currentPointId =
                Optional.ofNullable(handleService.getOne(Wrappers.lambdaQuery(new TopicHandleDetail())
                                .select(TopicHandleDetail::getTopicId, TopicHandleDetail::getCurrentPointId)
                                .eq(TopicHandleDetail::getTopicId, topicId)
                                .last("LIMIT 1")
                        ))
                        .map(TopicHandleDetail::getCurrentPointId)
                        .orElse(null);

        // 执行当前节点到下一个节点
        flowService.nextPoint(vo, currentPointId);

        return ResponseEntity.okMsg("执行成功");
    }

    private void validatedRoleAccess(Long currentPointId){
        // 获取请求的用户信息
        UserDetailVO userDetail = Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
                .map(item -> (String) item.getPrincipal())
                .map(userName -> userService.queryUserDetail(new UserDO().setUserName(userName)))
                .orElseThrow(() -> new ServiceException("获取用户信息失败"));

        // 超级管理员不校验
        if(userDetail.getIsSuperAdmin()) return;

        // 获取用户绑定的节点列表
        Set<Long> accessPointIds = userDetail.getResources().stream()
                .map(ResourceDO::getId)
                .collect(Collectors.toSet());

        if(!accessPointIds.contains(currentPointId)){
            throw new ServiceException("当前用户角色没有该操作权限");
        }
    }

}
